package com.yk.system.controller;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yk.api.system.dto.MessageCountDTO;
import com.yk.api.system.dto.MessageDTO;
import com.yk.common.core.constant.NumberConstant;
import com.yk.common.core.domain.BasePageQuery;
import com.yk.common.core.domain.PageResult;
import com.yk.common.core.domain.Result;
import com.yk.common.core.utils.LoginHelper;
import com.yk.system.convert.MessageConvert;
import com.yk.system.entity.Message;
import com.yk.system.service.MessageService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Objects;


/**
 * 消息 前端控制器
 *
 * @author lmx
 * @since 2023-12-16
 */
@Api(tags = "消息")
@RestController
@RequiredArgsConstructor
@RequestMapping("/message")
public class MessageController {

    private final MessageService messageService;
    private final MessageConvert messageConvert;

    @GetMapping("/getById/{id}")
    @ApiOperation("消息-查询单个")
    public Result<Message> getById(@PathVariable(value = "id") Long id) {
        return Result.data(messageService.getById(id));
    }

    @PostMapping("/save")
    @ApiOperation("消息-新增")
    public Result<Boolean> save(@RequestBody @Validated MessageDTO dto) {
        return Result.data(messageService.save(messageConvert.dto2Entity(dto)));
    }

    @PostMapping("/update")
    @ApiOperation("消息-修改")
    public Result<Boolean> updateById(@RequestBody @Validated MessageDTO dto) {
        return Result.data(messageService.updateById(messageConvert.dto2Entity(dto)));
    }

    @GetMapping("/deleteById/{id}")
    @ApiOperation("消息-删除")
    public Result<Boolean> deleteById(@PathVariable(value = "id") Long id) {
        return Result.data(messageService.removeById(id));
    }

    @PostMapping("/list")
    @ApiOperation("消息-查询列表")
    public Result<List<Message>> list(@RequestBody MessageDTO param) {
        LambdaQueryWrapper<Message> lambda = new LambdaQueryWrapper<>();
        lambda.eq(Message::getUserId, LoginHelper.getLoginUserId());
        lambda.eq(StrUtil.isNotEmpty(param.getType()), Message::getType, param.getType());
        return Result.data(messageService.list(lambda));
    }

    @PostMapping("/page")
    @ApiOperation("消息-分页查询")
    public PageResult<Message> page(@RequestBody BasePageQuery<MessageDTO> pageParam) {
        MessageDTO param = pageParam.getParam();
        LambdaQueryWrapper<Message> lambda = new LambdaQueryWrapper<>();
        buildCondition(lambda, param);
        IPage<Message> page = messageService.page(new Page<>(pageParam.getPageNum(), pageParam.getPageSize()), lambda);
        return PageResult.success(page.getRecords(), page.getTotal());
    }

    @PostMapping("/pageByTime")
    @ApiOperation("消息-根据时间分页查询")
    public PageResult<Message> pageByTime(@RequestBody BasePageQuery<MessageDTO> pageParam) {
        MessageDTO param = pageParam.getParam();
        Assert.notNull(param.getType(), "消息类型不能为空");
        param.setUserId(LoginHelper.getLoginUserId());
        List<Message> list = messageService.pageByTime(param);
        if (CollUtil.isEmpty(list)) {
            return PageResult.success(CollUtil.newArrayList(), 0);
        }
        int index = 0;
        if (Objects.isNull(param.getId())){
            index = CollUtil.indexOf(list, matcher -> matcher.getId().equals(param.getId()));
        }
        if (index > -1) {
            int start = index == 0 ? 0 : index + 1;
            int toIndex = start + pageParam.getPageSize().intValue();
            if (list.size() < toIndex) {
                toIndex = list.size();
            }
            list = list.subList(start, toIndex);
        }
        Integer total = messageService.countPageByTime(param);
        return PageResult.success(list, total);
    }

    @PostMapping("/update2Stats")
    @ApiOperation("消息-已读")
    public Result<Boolean> update2Stats(@RequestBody @Validated MessageDTO dto) {
        Assert.notNull(dto.getId(), "消息id不能为空");
        Message message = messageService.getById(dto.getId());
        Assert.notNull(dto.getId(), "消息不存在");
        message.setStatus(Boolean.TRUE);
        return Result.data(messageService.updateById(message));
    }

    @PostMapping("/update2StatsList")
    @ApiOperation("消息-一键已读")
    public Result<Boolean> update2StatsList(@RequestBody @Validated MessageDTO dto) {
        if (CollUtil.isEmpty(dto.getIds())) {
            return Result.fail("消息id不能为空");
        }
        List<Message> list = messageService.list(new LambdaQueryWrapper<Message>().in(Message::getId, dto.getIds()));
        for (Message message : list) {
            message.setStatus(Boolean.TRUE);
        }
        return Result.data(messageService.updateBatchById(list));
    }

    @PostMapping("/countNum")
    @ApiOperation("消息-未读数量")
    public Result<MessageCountDTO> countNum() {
        LambdaQueryWrapper<Message> lambda = new LambdaQueryWrapper<>();
        lambda.eq(Message::getUserId, LoginHelper.getLoginUserId());
        lambda.eq(Message::getStatus, false);
        List<Message> list = messageService.list(lambda);
        if (CollUtil.isEmpty(list)) {
            return Result.data(new MessageCountDTO(0, 0));
        }
        Long count = list.stream().filter(it -> NumberConstant.ONE_STR.equals(it.getType())).count();
        return Result.data(new MessageCountDTO(list.size() - count.intValue(), count.intValue()));
    }

    @PostMapping("/systemMessage")
    @ApiOperation("消息入库")
    public Result<Void> systemMessage(@RequestParam("title") String title,
                                      @RequestParam("userId") Long userId,
                                      @RequestParam("content") String content,
                                      @RequestParam("type") String type) {
        messageService.systemMessage(title, userId, content, type);
        return Result.ok();
    }


    /**
     * 构造查询条件
     */
    private void buildCondition(LambdaQueryWrapper<Message> lambda, MessageDTO param) {
        lambda.eq(Message::getUserId, LoginHelper.getLoginUserId());
        lambda.eq(Objects.nonNull(param.getStatus()), Message::getStatus, param.getStatus());
        lambda.eq(StrUtil.isNotEmpty(param.getType()), Message::getType, param.getType());
        if (Objects.nonNull(param.getStartTime())) {
            lambda.between(Message::getUpdatedAt, param.getStartTime(), param.getEndTime());
        }
        lambda.orderByDesc(Message::getUpdatedAt);
    }

}